from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy import func
from sqlalchemy.ext.mutable import MutableDict
from models.engine import db
from models.types import StringUUID


class RobTimbre(db.Model):
    __tablename__ = "rob_timbre"
    __table_args__ = (db.PrimaryKeyConstraint("id", name="rob_timbre_pkey"),
                      db.Index("rob_timbre_tenant_idx", "tenant_id"))
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False, comment="租户ID")
    name = db.Column(db.String(128), nullable=False,)
    descrip = db.Column(db.String(512), nullable=False, comment="说明描述")
    timbre_code = db.Column(db.String(64), nullable=False,)
    price = db.Column(db.Integer, nullable=False, default=0, comment="价格/分")
    provider_id = db.Column(StringUUID, nullable=False, comment="api提供商ID")
    rate = db.Column(db.Integer, nullable=False,
                     default=16000, comment="默认采样率")
    config = db.Column(MutableDict.as_mutable(JSONB), nullable=True,server_default=db.text('{}'),comment="配置")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)
    @property
    def provider(self)->"RobTimbreProvider|None":
        if self.provider_id:
            return db.session.get(RobTimbreProvider, self.provider_id)
        return None
    @property
    def provider_name(self)->str:
        return self.provider.name if self.provider else ""
    def to_dict(self)->dict:
        return {
            "id": self.id,
            "tenant_id": self.tenant_id,
            "name": self.name,
            "descrip": self.descrip,
            "price": self.price,
            "rate":self.rate,
            "provider": self.provider.to_dict() if self.provider else {},
            "created_by": self.created_by,
        }
    
    @property
    def voice_example(self)->dict:
        if self.config:
            return self.config.get("voice_example",{})
        return {}
    
    @voice_example.setter
    def voice_example(self,voice_example:dict):
        self.config = self.config or {}
        if "content" not in voice_example or "url" not in voice_example:
            raise ValueError("voice_example must contain 'content' and 'url'")
        self.config["voice_example"] = voice_example

    @property
    def emotion_predict_agent_id(self)->str|None:
        if self.config is None:
            return None
        return self.config.get("emotion_predict_agent_id","")
    
    @emotion_predict_agent_id.setter
    def emotion_predict_agent_id(self,value:str|None):
        self.config = self.config or {}
        self.config["emotion_predict_agent_id"] = value

    
    @property
    def suport_languages(self)->list[str]:
        if self.config:
            return self.config.get("suport_languages",[])
        return []
    
    @suport_languages.setter
    def suport_languages(self,value:list[str]):
        self.config = self.config or {}
        self.config["suport_languages"] = value

class RobTimbreProvider(db.Model):
    __tablename__ = "rob_timbre_provider"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='rob_timbre_provider_pkey'),
        db.Index('rob_timbre_provider_tenant_idx', 'tenant_id'),
        db.Index('rob_timbre_provider_code_idx','provider_code',unique=True)
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False,)
    name = db.Column(db.String(64), nullable=False,)
    provider_code = db.Column(db.String(32), nullable=False,)
    auth_config = db.Column(MutableDict.as_mutable(JSONB), nullable=False, default={})
    provider_config = db.Column(MutableDict.as_mutable(JSONB), nullable=False, default={})
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)

    @property
    def timbres(self) -> list[RobTimbre]:
        return db.session.query(RobTimbre).filter(RobTimbre.tenant_id == self.tenant_id, RobTimbre.provider_id == self.id).all()
    def to_dict(self)->dict:
        return {
            "id": self.id,
            "name": self.name,
            "provider_config": self.provider_config,
            "tenant_id": self.tenant_id,
            "created_by": self.created_by,
        }
    
    def to_server_init_dict(self)->dict:
        return {
            "id": self.id,
            "name": self.name,
            "provider_code":self.provider_code,
            "auth_config":self.auth_config,
            "provider_config": self.provider_config,
        }
    

class RobTimbreHVERMap(db.Model):
    __tablename__ = "rob_timbre_hver_map"
    __table_args__ = (
        db.PrimaryKeyConstraint('timbre_id', 'hver',
                                name='idx_rob_timbre_hver_map_pk'),
        db.Index('idx_rob_timbre_hver_map_hver', 'hver'),
    )
    hver = db.Column(db.String(32), nullable=False, comment="硬件版本")
    timbre_id = db.Column(StringUUID, nullable=False, comment="音色id")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    